home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PAS_0693 / DSWRITE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-06-30  |  4KB  |  115 lines

  1. {─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
  2. Msg  : 300 of 319                                                               
  3. From : Sean Palmer                         1:104/123.0          22 Jun 93  23:10 
  4. To   : Lou Duchez                                                                
  5. Subj : Fast Direct Writes                                                     
  6. ────────────────────────────────────────────────────────────────────────────────
  7. LD>SP>I've optimized it a little, if you're interested... 8)
  8.  
  9. LD>SP>procedure qwrite(x, y: byte; s: string; f, b: byte);
  10.  
  11. LD>Interesting optimizations -- do I assume that Inc, Dec, Pred, and Succ
  12. LD>are faster than I had ever imagined?  (Shoot, I always figured they'd be
  13. LD>a lot slower than normal arithmetic!)  Thanks!
  14.  
  15. Succ and Pred are faster for byte-sized ordinals (at least in TP 6.0)
  16. than +1 and -1. The same for word-size. See, with +1 and -1, the byte
  17. gets converted into a word first, but with Succ() and Pred() it
  18. stays a byte... Inc(I) is faster than I:=I+1 or I:=Succ(I) stuff in 6.0
  19. but I think 7.0+ optimize them all to the same code...not sure, I don't
  20. have 7.0...8(
  21.  
  22. Actually the fastest part of what I did is to pre-calculate the
  23. attribute as the hi byte of a word, and use word stores instead of byte
  24. stores. Could be done alot faster in assembly (don't access any
  25. memory-based variables that way, it's all in registers..8)
  26.  
  27. Here is a direct screen write unit I wrote in BASM. VERY fast...}
  28.  
  29. {$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X+}
  30. unit dswrite;
  31. interface
  32. const
  33.  vSeg:word=$B800;  {change for mono}
  34.  
  35. {in following parms, s=source,d=destination,n=count, words are offsets
  36.  into video memory (you calculate them with ((y*80+x)*2)}
  37. {I did this mainly so less parms would have to be sent, as TP does a
  38.  good job of the arithmetic for that expression...Oh well if you really
  39.  don't like it I could make these use x and y coords, but this was
  40.  basically chopped from another project of mine..}
  41.  
  42. procedure moveScr(s,d,n:word);  {one part of screen to another}
  43. procedure toScr(var s;d,n:word);  {from string to video ram}
  44. procedure toScrA(var s;d,n:word;a:byte); {ditto with attribute also}
  45. procedure fillScr(d,n:word;c:char);      {mainly useful for rows}
  46. procedure fillAttr(d,n:word;a:byte);     {ditto}
  47.  
  48. implementation
  49.  
  50. procedure moveScr(s,d,n:word);assembler;asm
  51.  mov cx,n; jcxz @X;
  52.  push ds; mov ax,vSeg; mov es,ax; mov ds,ax;
  53.  mov si,s; shl si,1;
  54.  mov di,d; shl di,1;
  55.  cmp si,di; jb @REV;  {move in reverse to prevent overwrite}
  56.  cld; jmp @GO;
  57. @REV: std; shl cx,1; add si,cx; add di,cx; shr cx,1; {start at end}
  58. @GO: repz movsw; {move attr too!}
  59.  pop ds;
  60. @X:
  61.  end;
  62.  
  63. procedure toScr(var s;d,n:word);assembler;asm
  64.  mov cx,n; jcxz @X;
  65.  push ds; mov es,vSeg;
  66.  mov di,d; shl di,1;
  67.  lds si,s; cld;
  68. @L: movsb; inc di; loop @L;
  69.  pop ds;
  70. @X:
  71.  end;
  72.  
  73. procedure toScrA(var s;d,n:word;a:byte);assembler;asm
  74.  mov cx,n; jcxz @X;
  75.  push ds; mov es,vSeg;
  76.  mov di,d; shl di,1;
  77.  lds si,s; cld;
  78.  mov al,a;  {attribute}
  79. @L: movsb; {doesn't affect al reg}
  80.  stosb; loop @L;
  81.  pop ds;
  82. @X:
  83.  end;
  84.  
  85. procedure fillScr(d,n:word;c:char);assembler;asm
  86.  mov cx,n; jcxz @X;
  87.  mov es,vSeg;
  88.  mov di,d; shl di,1;
  89.  mov al,c; cld;
  90. @L: stosb; inc di; loop @L;
  91. @X:
  92.  end;
  93.  
  94. procedure fillAttr(d,n:word;a:byte);assembler;asm
  95.  mov cx,n; jcxz @X;
  96.  mov es,vSeg;
  97.  mov di,d; shl di,1;
  98.  mov al,a; cld;
  99. @L: inc di; stosb; loop @L;
  100. @X:
  101.  end;
  102.  
  103. end.
  104.  
  105. Keep in mind these are VERY low-level and aren't necessarily gonna be
  106. easy to work with but they are, by god, FAST.
  107.  
  108. LD>As to why I pass attributes and don't use WhereX() and WhereY(), I wrote
  109. LD>QWRITE mostly for screen drawing -- in fact, QWRITE doesn't even move the
  110. LD>cursor.  It's no good for "scrolling" text, but goldang, when you want
  111. LD>to draw a box on the screen or fill a region with a given character ...
  112.  
  113. These don't either (cursor? who needs it!)
  114.  
  115. QWrite'll work a little faster now, anyway...